package io.acna.mybatis.plugins.core;

import io.acna.mybatis.plugins.core.enums.EConnect;
import io.acna.mybatis.plugins.core.enums.ERelation;
import io.acna.mybatis.plugins.core.enums.ESort;

import java.io.Serializable;
import java.util.*;

public class IndieCondition implements Serializable {

    private EConnect connect = EConnect.AND;
    private ESort sort = ESort.DESC;
    private int pagNum = 55;
    private int rows;
    private boolean where = true;
    private RowBound rowBound;

    private Map<Map<String, Object>, ERelation> search = new HashMap<>();
    private List<String> sorts = new ArrayList<>();
    private List<String> groups = new ArrayList<>();
    private Map<String, Object[]> beteens = new HashMap<>();
    private Map<String, Boolean> nulls = new HashMap<>();


    /**
     * 添加一个查询条件
     *
     * @param column  列名
     * @param value   值
     * @param connect 列与值的连接关系(例如" like "、" = "等)
     * @return this
     */
    public IndieCondition add(String column, Object value, ERelation connect) {
        if (connect == null)
            connect = ERelation.EQUAL;
        Map<String, Object> map = new HashMap<>();
        map.put(column, value);
        this.search.put(map, connect);
        return this;
    }

    /**
     * 添加一个查询条件(默认关系连接连接为"=")
     *
     * @param column 列名
     * @param value  值
     * @return this
     */
    public IndieCondition add(String column, Object value) {
        return add(column, value, null);
    }

    /**
     * 条件拼装为OR查询(和AND拼装相对)
     *
     * @return this
     */
    public IndieCondition or() {
        this.connect = EConnect.OR;
        return this;
    }

    /**
     * 添加GroupBy参数
     *
     * @param column 列名
     * @return this
     */
    public IndieCondition groupBy(String column) {
        this.groups.add(column);
        return this;
    }

    /**
     * 排序(默认排序方式DESC)
     *
     * @param column 列名
     * @return this
     */
    public IndieCondition orderBy(String column) {
        this.sorts.add(column);
        return this;
    }

    /**
     * ASC排序方式(没有orderBy方法调用时此方法参数无效)
     *
     * @return this
     */
    public IndieCondition asc() {
        this.sort = ESort.ASC;
        return this;
    }

    /**
     * between条件拼装
     *
     * @param column   列名
     * @param startVal 开始值
     * @param endVal   结束值
     * @return this
     */
    public IndieCondition between(String column, Object startVal, Object endVal) {
        Object[] objects = new Object[2];
        objects[0] = startVal;
        objects[1] = endVal;
        this.beteens.put(column, objects);
        return this;
    }


    /**
     * 添加为空或者非空条件
     *
     * @param column 列名
     * @param isNull 是否为空
     * @return this
     */
    public IndieCondition isNull(String column, Boolean isNull) {
        if (isNull == null)
            isNull = true;
        nulls.put(column, isNull);
        return this;
    }

    /**
     * 添加为空的条件
     *
     * @param column IS null的列名
     * @return this
     */
    public IndieCondition isNull(String column) {
        return isNull(column, null);
    }

    /**
     * 再已有的条件上进行拼接(参数连接符非WHERE而是AND)
     *
     * @return this
     */
    public IndieCondition notWhere() {
        this.setWhere(false);
        return this;
    }

    public IndieCondition queryAll() {
        this.setPagNum(0);
        this.setRows(0);
        return this;
    }

    public IndieCondition(int pagNum, int rows) {
        this.pagNum = pagNum;
        this.rows = rows;
    }


    /**
     * build
     */

    public static IndieCondition buildQueryAll() {
        return new IndieCondition(0, 0);
    }

    public static IndieCondition buildQuery(int pagNum, int rows) {
        return new IndieCondition(pagNum, rows);
    }

    public IndieCondition() {
    }

    public RowBound getRowBound() {
        return new RowBound(this.getPagNum(), this.getRows());
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public int getPagNum() {
        return pagNum;
    }

    public void setPagNum(int pagNum) {
        this.pagNum = pagNum;
    }

    public Map<Map<String, Object>, ERelation> getSearch() {
        return search;
    }

    public void setSearch(Map<Map<String, Object>, ERelation> search) {
        this.search = search;
    }

    public EConnect getConnect() {
        return connect;
    }

    public boolean isWhere() {
        return where;
    }

    public void setWhere(boolean where) {
        this.where = where;
    }

    public void setConnect(EConnect connect) {
        this.connect = connect;
    }

    public ESort getSort() {
        return sort;
    }

    public void setSort(ESort sort) {
        this.sort = sort;
    }

    public List<String> getSorts() {
        return sorts;
    }

    public void setSorts(List<String> sorts) {
        this.sorts = sorts;
    }

    public Map<String, Object[]> getBeteens() {
        return beteens;
    }

    public void setBeteens(Map<String, Object[]> beteens) {
        this.beteens = beteens;
    }

    public Map<String, Boolean> getNulls() {
        return nulls;
    }

    public void setNulls(Map<String, Boolean> nulls) {
        this.nulls = nulls;
    }

    public void setRowBound(RowBound rowBound) {
        this.rowBound = rowBound;
    }

    public List<String> getGroups() {
        return groups;
    }

    public void setGroups(List<String> groups) {
        this.groups = groups;
    }
}
